import Foundation public extension Disk { /// Save an array of Data objects to disk /// /// - Parameters: /// - value: array of Data to store to disk /// - directory: user directory to store the files in /// - path: folder location to store the data files (i.e. "Folder/") /// - Throws: Error if there were any issues creating a folder and writing the given [Data] to files in it static func save(_ value: [Data], to directory: Directory, as path: String) throws { do { let folderUrl = try createURL(for: path, in: directory) try createSubfoldersBeforeCreatingFile(at: folderUrl) try FileManager.default.createDirectory(at: folderUrl, withIntermediateDirectories: false, attributes: nil) for i in 0 ..< value.count { let data = value[i] let dataName = "\(i)" let dataUrl = folderUrl.appendingPathComponent(dataName, isDirectory: false) try data.write(to: dataUrl, options: .atomic) } } catch { throw error } } /// Append a file with Data to a folder /// /// - Parameters: /// - value: Data to store to disk /// - directory: user directory to store the file in /// - path: folder location to store the data files (i.e. "Folder/") /// - Throws: Error if there were any issues writing the given data to disk static func append(_ value: Data, to path: String, in directory: Directory) throws { do { if let folderUrl = try? getExistingFileURL(for: path, in: directory) { let fileUrls = try FileManager.default.contentsOfDirectory( at: folderUrl, includingPropertiesForKeys: nil, options: [] ) var largestFileNameInt = -1 for i in 0 ..< fileUrls.count { let fileUrl = fileUrls[i] if let fileNameInt = fileNameInt(fileUrl) { if fileNameInt > largestFileNameInt { largestFileNameInt = fileNameInt } } } let newFileNameInt = largestFileNameInt + 1 let data = value let dataName = "\(newFileNameInt)" let dataUrl = folderUrl.appendingPathComponent(dataName, isDirectory: false) try data.write(to: dataUrl, options: .atomic) } else { let array = [value] try save(array, to: directory, as: path) } } catch { throw error } } /// Append an array of data objects as files to a folder /// /// - Parameters: /// - value: array of Data to store to disk /// - directory: user directory to create folder with data objects /// - path: folder location to store the data files (i.e. "Folder/") /// - Throws: Error if there were any issues writing the given Data static func append(_ value: [Data], to path: String, in directory: Directory) throws { do { if let _ = try? getExistingFileURL(for: path, in: directory) { for data in value { try append(data, to: path, in: directory) } } else { try save(value, to: directory, as: path) } } catch { throw error } } /// Retrieve an array of Data objects from disk /// /// - Parameters: /// - path: path of folder that's holding the Data objects' files /// - directory: user directory where folder was created for holding Data objects /// - type: here for Swifty generics magic, use [Data].self /// - Returns: [Data] from disk /// - Throws: Error if there were any issues retrieving the specified folder of files static func retrieve(_ path: String, from directory: Directory, as _: [Data].Type) throws -> [Data] { do { let url = try getExistingFileURL(for: path, in: directory) let fileUrls = try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: []) let sortedFileUrls = fileUrls.sorted(by: { (url1, url2) -> Bool in if let fileNameInt1 = fileNameInt(url1), let fileNameInt2 = fileNameInt(url2) { return fileNameInt1 <= fileNameInt2 } return true }) var dataObjects = [Data]() for i in 0 ..< sortedFileUrls.count { let fileUrl = sortedFileUrls[i] let data = try Data(contentsOf: fileUrl) dataObjects.append(data) } return dataObjects } catch { throw error } } }